home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- * Generic parser for the "Irit" solid modeller. *
- * *
- * Written by: Gershon Elber Ver 0.2, Sep. 1991 *
- *****************************************************************************/
-
- #ifdef USE_VARARGS
- #include <varargs.h>
- #else
- #include <stdarg.h>
- #endif /* USE_VARARGS */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <math.h>
- #include <string.h>
- #include <setjmp.h>
- #include "irit_sm.h"
- #include "prsr_loc.h"
- #include "allocate.h"
- #include "attribut.h"
- #include "irit_soc.h"
-
- #ifdef __WINNT__
- #include <fcntl.h>
- #include <io.h>
- #endif /* __WINNT__ */
-
- #define CONVEX_EPSILON 1e-3
- #define ZERO_NUM_EPSILON 1e-15
- #define NORMAL_MIN_VALID_LEN 0.03
-
- static char
- GlblTokenError[LINE_LEN_LONG]; /* Last token error was found. */
- static IritPrsrPrintFuncType
- IritPrsrPrintFunc = NULL;
-
- jmp_buf _IritPrsrLongJumpBuffer; /* Used in error traping. */
- int _IritPrsrPolyListCirc = FALSE,
- _IritPrsrGlblParserError = IP_NO_ERR, /* Last err # found. */
- _IritPrsrReadOneObject = FALSE, /* If only one object is to be read. */
- IritPrsrWasViewMat = FALSE,
- IritPrsrWasPrspMat = FALSE;
- char
- *_IPGlblFloatFormat = "%lg";
-
- MatrixType IritPrsrViewMat = { /* Isometric view, by default. */
- { -0.707107, -0.408248, 0.577350, 0.000000 },
- { 0.707107, -0.408248, 0.577350, 0.000000 },
- { 0.000000, 0.816496, 0.577350, 0.000000 },
- { 0.000000, 0.000000, 0.000000, 1.000000 }
- };
- MatrixType IritPrsrPrspMat = {
- { 1, 0, 0, 0 },
- { 0, 1, 0, 0 },
- { 0, 0, 1, -0.35 },
- { 0, 0, 0, 1.0 }
- };
-
- static void IritPrsrPutAttributes(int Handler,
- IPAttributeStruct *Attr,
- int Indent);
- static void IritPrsrPutAllObjects(IPObjectStruct *PObj,
- int Handler,
- int Indent);
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Routine to update the Plane equation of the given polygon by the order M
- * of the most robust three vertices of that polygon to define the normal. M
- * *
- * PARAMETERS: M
- * PPoly: To update its normal/plane equation. M
- * *
- * RETURN VALUE: M
- * void M
- * *
- * KEYWORDS: M
- * IritPrsrUpdatePolyPlane, files, parser M
- *****************************************************************************/
- void IritPrsrUpdatePolyPlane(IPPolygonStruct *PPoly)
- {
- int i;
- RealType Len, V1[3], V2[3],
- MaxLen = SQR(EPSILON);
- IPVertexStruct
- *VLast = NULL,
- *V = PPoly -> PVertex;
- PlaneType Plane;
-
- if (V == NULL || V -> Pnext == NULL || V -> Pnext -> Pnext == NULL)
- _IPParserAbort(IP_ERR_DEGEN_POLYGON, "");
-
- for (i = 0; i < 4; i++)
- PPoly -> Plane[i] = 0.0;
-
- /* Force list to be circular. Will be recovered immediately after. */
- if (!_IritPrsrPolyListCirc) {
- VLast = IritPrsrGetLastVrtx(V);
- VLast -> Pnext = V;
- }
-
- do {
- PT_SUB(V1, V -> Coord, V -> Pnext -> Coord);
- V = V -> Pnext;
- PT_SUB(V2, V -> Coord, V -> Pnext -> Coord);
-
- Plane[0] = V1[1] * V2[2] - V2[1] * V1[2];
- Plane[1] = V1[2] * V2[0] - V2[2] * V1[0];
- Plane[2] = V1[0] * V2[1] - V2[0] * V1[1];
-
- /* Normalize the plane such that the normal has length of 1: */
- Len = PT_LENGTH(Plane);
- if (Len > MaxLen) {
- for (i = 0; i < 3; i++)
- PPoly -> Plane[i] = Plane[i] / Len;
-
- MaxLen = Len;
-
- if (MaxLen > SQR(NORMAL_MIN_VALID_LEN))
- break;
- }
-
- V = V -> Pnext;
- }
- while (V != PPoly -> PVertex &&
- V -> Pnext != NULL &&
- V -> Pnext -> Pnext != NULL);
-
- if (VLast != NULL) /* Recover non circular list, if was non circular. */
- VLast -> Pnext = NULL;
-
- if (MaxLen < SQR(EPSILON))
- _IPParserAbort(IP_ERR_DEGEN_NORMAL, "");
-
- PPoly -> Plane[3] =
- -DOT_PROD(PPoly -> Plane, PPoly -> PVertex -> Coord);
-
- IP_SET_PLANE_POLY(PPoly);
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Routine to update the Plane equation of the given polygon such that the M
- * Vin vertex will be in the positive side of it. M
- * *
- * PARAMETERS: M
- * PPoly: To update its normal/plane equation. M
- * Vin: A vertex to be considered in the inside, respective to PPoly. M
- * *
- * RETURN VALUE: M
- * void M
- * *
- * KEYWORDS: M
- * IritPrsrUpdatePolyPlane2, files, parser M
- *****************************************************************************/
- void IritPrsrUpdatePolyPlane2(IPPolygonStruct *PPoly, VectorType Vin)
- {
- int i;
-
- IritPrsrUpdatePolyPlane(PPoly);
-
- if (DOT_PROD(PPoly -> Plane, Vin) + PPoly -> Plane[3] < 0) {
- /* Flip plane normal and reverse the vertex list. */
- IritPrsrReverseVrtxList(PPoly);
- for (i = 0; i < 4; i++)
- PPoly -> Plane[i] = (-PPoly -> Plane[i]);
- }
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Routine to update all vertices in polygon to hold a default normal if M
- * have none already. M
- * *
- * PARAMETERS: M
- * PPoly: Polygon to update normal information. M
- * DefNrml: Normal tp use in update. M
- * *
- * RETURN VALUE: M
- * void M
- * *
- * KEYWORDS: M
- * IritPrsrUpdateVrtxNrml, files, parser M
- *****************************************************************************/
- void IritPrsrUpdateVrtxNrml(IPPolygonStruct *PPoly, VectorType DefNrml)
- {
- IPVertexStruct
- *V = PPoly -> PVertex;
-
- do {
- if (!IP_HAS_NORMAL_VRTX(V)) {
- PT_COPY(V -> Normal, DefNrml);
- IP_SET_NORMAL_VRTX(V);
- }
- V = V -> Pnext;
- }
- while (V != NULL && V != PPoly -> PVertex);
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Reverses a list of objects, in place. M
- * *
- * PARAMETERS: M
- * PObj: A list of objects to reverse. M
- * *
- * RETURN VALUE: M
- * IPObjectStruct *: Reverse list of objects, in place. M
- * *
- * KEYWORDS: M
- * IritPrsrReverseObjList, reverse, files, parser M
- * M
- *****************************************************************************/
- IPObjectStruct *IritPrsrReverseObjList(IPObjectStruct *PObj)
- {
- IPObjectStruct
- *NewPObjs = NULL;
-
- while (PObj) {
- IPObjectStruct
- *Pnext = PObj -> Pnext;
-
- PObj -> Pnext = NewPObjs;
- NewPObjs = PObj;
-
- PObj = Pnext;
- }
-
- return NewPObjs;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Reverses the vertex list of a given polygon. This is used mainly to M
- * reverse polygons such that cross product of consecutive edges which form M
- * a convex corner will point in the polygon normal direction. M
- * *
- * PARAMETERS: M
- * Pl: A polygon to reverse its vertex list, in place. M
- * *
- * RETURN VALUE: M
- * void M
- * *
- * KEYWORDS: M
- * IritPrsrReverseVrtxList , reverse, files, parser M
- *****************************************************************************/
- void IritPrsrReverseVrtxList(IPPolygonStruct *Pl)
- {
- ByteType Tags, Count;
- IPVertexStruct *VNextNext, *VLast,
- *V = Pl -> PVertex,
- *VNext = V -> Pnext;
-
- /* Force list to be circular. Will be recovered immediately after. */
- if (!_IritPrsrPolyListCirc) {
- VLast = IritPrsrGetLastVrtx(V);
- VLast -> Pnext = V;
- }
-
- do {
- VNextNext = VNext -> Pnext;
- VNext -> Pnext = V; /* Reverse the pointer! */
-
- V = VNext; /* Advance all 3 pointers by one. */
- VNext = VNextNext;
- VNextNext = VNextNext -> Pnext;
- }
- while (V != Pl -> PVertex);
-
- V = Pl -> PVertex; /* Move the Tags/Count by one - to the right edge. */
- Tags = V -> Tags;
- Count = V -> Count;
- do {
- if (V -> Pnext == Pl -> PVertex) {
- V -> Tags = Tags;
- V -> Count = Count;
- }
- else {
- V -> Tags = V -> Pnext -> Tags;
- V -> Count = V -> Pnext -> Count;
- }
-
- V = V -> Pnext;
- }
- while (V != Pl -> PVertex);
-
- /* Recover non circular list, if needs to. */
- if (!_IritPrsrPolyListCirc) {
- VLast = IritPrsrGetLastVrtx(Pl -> PVertex);
- VLast -> Pnext = NULL;
- }
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Routine to abort parsing operation and save error reported. M
- * See also function IritPrsrParseError. M
- * *
- * PARAMETERS: M
- * ErrNum: Type of error that had occured. M
- * Msg: A message to accompany the error number. M
- * *
- * RETURN VALUE: M
- * void M
- * *
- * KEYWORDS: M
- * _IPParserAbort, error handling, files, parser M
- *****************************************************************************/
- void _IPParserAbort(IritPrsrErrType ErrNum, char *Msg)
- {
- _IritPrsrGlblParserError = ErrNum;
- strcpy(GlblTokenError, Msg); /* Keep the message in safe place... */
-
- longjmp(_IritPrsrLongJumpBuffer, 1); /* Jump to... */
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Returns TRUE if error has happend since last call to this function during M
- * data read or write, FALSE otherwise. M
- * If error, then ErrorMsg is updated to point on static str describing it. M
- * *
- * PARAMETERS: M
- * LineNum: Line number of error, in file/stream. M
- * ErrorMsg: To be updated with latest error to have happened in parser. M
- * *
- * RETURN VALUE: M
- * int: TRUE if error occured since last call, FALSE otherwise. M
- * *
- * KEYWORDS: M
- * IritPrsrParseError, error handling, files, parser M
- *****************************************************************************/
- int IritPrsrParseError(int LineNum, char **ErrorMsg)
- {
- IritPrsrErrType Temp;
- char TempCopy[LINE_LEN_LONG];
-
- if ((Temp = _IritPrsrGlblParserError) == IP_NO_ERR)
- return FALSE;
-
- strcpy(TempCopy, GlblTokenError);
- _IritPrsrGlblParserError = IP_NO_ERR;
-
- switch (Temp) {
- case IP_ERR_NUMBER_EXPECTED:
- sprintf(GlblTokenError, "Line %d: Numeric data expected - found %s",
- LineNum, TempCopy);
- break;
- case IP_ERR_OPEN_PAREN_EXPECTED:
- sprintf(GlblTokenError, "Line %d: '[' expected - found '%s'",
- LineNum, TempCopy);
- break;
- case IP_ERR_CLOSE_PAREN_EXPECTED:
- sprintf(GlblTokenError, "Line %d: ']' expected - found '%s'",
- LineNum, TempCopy);
- break;
- case IP_ERR_LIST_COMP_UNDEF:
- sprintf(GlblTokenError, "Line %d: Undefined list element - \"%s\"",
- LineNum, TempCopy);
- break;
- case IP_ERR_UNDEF_EXPR_HEADER:
- sprintf(GlblTokenError, "Line %d: Undefined TOKEN - \"%s\"",
- LineNum, TempCopy);
- break;
- case IP_ERR_PT_TYPE_EXPECTED:
- sprintf(GlblTokenError, "Line %d: Point type expected",
- LineNum);
- break;
- case IP_ERR_OBJECT_EMPTY:
- sprintf(GlblTokenError, "Line %d: Empty object found",
- LineNum);
- break;
- case IP_ERR_FILE_EMPTY:
- sprintf(GlblTokenError, "Line %d: Empty object found",
- LineNum);
- break;
- case IP_ERR_MIXED_TYPES:
- sprintf(GlblTokenError,
- "Line %d: Mixed data types in same object",
- LineNum);
- break;
- case IP_ERR_STR_NOT_IN_QUOTES:
- sprintf(GlblTokenError,
- "Line %d: String not in quotes (%s)",
- LineNum, TempCopy);
- break;
- case IP_ERR_OBJECT_EXPECTED:
- sprintf(GlblTokenError,
- "Line %d: 'OBJECT' expected, found '%s'",
- LineNum, TempCopy);
- break;
- case IP_ERR_CAGD_LIB_ERR:
- case IP_ERR_TRIM_LIB_ERR:
- case IP_ERR_TRIV_LIB_ERR:
- sprintf(GlblTokenError, "Line %d: %s",
- LineNum, TempCopy);
- break;
- case IP_ERR_STACK_OVERFLOW:
- sprintf(GlblTokenError, "Line %d: Parser Stack overflow",
- LineNum);
- break;
- case IP_ERR_DEGEN_POLYGON:
- sprintf(GlblTokenError, "Line %d: Degenerate polygon",
- LineNum);
- break;
- case IP_ERR_DEGEN_NORMAL:
- sprintf(GlblTokenError, "Line %d: Degenerate normal",
- LineNum);
- break;
- case IP_ERR_SOCKET_BROKEN:
- sprintf(GlblTokenError, "Line %d: Socket connection is broken",
- LineNum);
- break;
- case IP_ERR_SOCKET_TIME_OUT:
- sprintf(GlblTokenError, "Line %d: Socket connection is broken",
- LineNum);
- break;
- case IP_ERR_BIN_IN_TEXT:
- sprintf(GlblTokenError, "Binary information in text file - %s",
- TempCopy);
- break;
- case IP_ERR_BIN_UNDEF_OBJ:
- sprintf(GlblTokenError, "Binary stream: Undefined object");
- break;
- default:
- sprintf(GlblTokenError,
- "Line %d: Data file parser - undefined error",
- LineNum);
- break;
- }
-
- *ErrorMsg = GlblTokenError;
-
- return TRUE;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Routine to test if the given polygon is convex (by IRIT definition) or M
- * not. M
- * Algorithm: The polygon is convex iff the normals generated from cross M
- * products of two consecutive edges points to the same direction. The same M
- * direction is tested by a positive dot product. M
- * *
- * PARAMETERS: M
- * Pl: To test for convexity. M
- * *
- * RETURN VALUE: M
- * int: TRUE if PL convex, FALSE otherwise. M
- * *
- * KEYWORDS: M
- * IritPrsrIsConvexPolygon, convexity, files, parser M
- *****************************************************************************/
- int IritPrsrIsConvexPolygon(IPPolygonStruct *Pl)
- {
- RealType Size, V1[3], V2[3], LastNormal[3], Normal[3];
- IPVertexStruct *VNext, *VNextNext,
- *V = Pl -> PVertex;
-
- LastNormal[0] = LastNormal[1] = LastNormal[2] = 0.0;
-
- do {
- if ((VNext = V -> Pnext) == NULL)
- VNext = Pl -> PVertex;
- if ((VNextNext = VNext -> Pnext) == NULL)
- VNextNext = Pl -> PVertex;
-
- PT_SUB(V1, VNext -> Coord, V -> Coord);
- if ((Size = PT_LENGTH(V1)) > EPSILON) {
- Size = 1.0 / Size;
- PT_SCALE(V1, Size);
- }
- PT_SUB(V2, VNextNext -> Coord, VNext -> Coord);
- if ((Size = PT_LENGTH(V2)) > EPSILON) {
- Size = 1.0 / Size;
- PT_SCALE(V2, Size);
- }
- CROSS_PROD(Normal, V1, V2);
-
- if (V != Pl -> PVertex) {
- if (PT_LENGTH(Normal) > CONVEX_EPSILON &&
- DOT_PROD(Normal, LastNormal) < -CONVEX_EPSILON)
- return FALSE;
- }
-
- PT_COPY(LastNormal, Normal);
-
- V = VNext;
- }
- while (V != Pl -> PVertex && V != NULL);
-
- return TRUE;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Routine to print the data from given object into stdout. M
- * *
- * PARAMETERS: M
- * PObj: To be put out to stdout. M
- * *
- * RETURN VALUE: M
- * void M
- * *
- * KEYWORDS: M
- * IritPrsrStdoutObject, files M
- *****************************************************************************/
- void IritPrsrStdoutObject(IPObjectStruct *PObj)
- {
- IritPrsrPutObjectToFile(stdout, PObj);
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Routine to print the data from given object into stderr. M
- * *
- * PARAMETERS: M
- * PObj: To be put out to stderr. M
- * *
- * RETURN VALUE: M
- * void M
- * *
- * KEYWORDS: M
- * IritPrsrStderrObject, files M
- *****************************************************************************/
- void IritPrsrStderrObject(IPObjectStruct *PObj)
- {
- IritPrsrPutObjectToFile(stderr, PObj);
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Routine to print the data from given object into given file FileName. M
- * If FileName is NULL or empty, print using IritPrsrPrintFunc. M
- * See function IritPrsrSetPrintFunc, IritPrsrSetFloatFormat. M
- * *
- * PARAMETERS: M
- * f: Output stream. M
- * PObj: Object to put on output stream. M
- * *
- * RETURN VALUE: M
- * void M
- * *
- * KEYWORDS: M
- * IritPrsrPutObjectToFile, files M
- *****************************************************************************/
- void IritPrsrPutObjectToFile(FILE *f, IPObjectStruct *PObj)
- {
- int Handler = -1;
-
- /* If the following gain control and is non zero - its from error! */
- if (setjmp(_IritPrsrLongJumpBuffer) != 0) {
- IritPrsrCloseStream(Handler, TRUE);
- return;
- }
-
- Handler = IritPrsrOpenStreamFromFile(f, FALSE, FALSE, FALSE);
-
- if (f != NULL && f != stdout && f != stderr)
- IRIT_DATA_HEADER(f, "Irit");
-
- if (_IPStream[Handler].IsBinary)
- IritPrsrPutBinObject(Handler, PObj);
- else
- IritPrsrPutAllObjects(PObj, Handler, 0);
-
- IritPrsrCloseStream(Handler, TRUE);
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Routine to print the data from given object into given file FileName. M
- * If FileName is NULL or empty, print using IritPrsrPrintFunc. M
- * See function IritPrsrSetPrintFunc, IritPrsrSetFloatFormat. M
- * *
- * PARAMETERS: M
- * Handler: A handler to the open stream. M
- * PObj: Object to put on output stream. M
- * *
- * RETURN VALUE: M
- * void M
- * *
- * KEYWORDS: M
- * IritPrsrPutObjectToHandler, files M
- *****************************************************************************/
- void IritPrsrPutObjectToHandler(int Handler, IPObjectStruct *PObj)
- {
- if (_IPStream[Handler].IsBinary)
- IritPrsrPutBinObject(Handler, PObj);
- else
- IritPrsrPutAllObjects(PObj, Handler, 0);
- }
-
- /*****************************************************************************
- * DESCRIPTION: *
- * Routine to print out the data from given object. *
- * *
- * PARAMETERS: *
- * PObj: Object to put out. *
- * Handler: A handler to the open stream. *
- * Indent: Indentation to put object at. *
- * *
- * RETURN VALUE: *
- * void *
- *****************************************************************************/
- static void IritPrsrPutAllObjects(IPObjectStruct *PObj,
- int Handler,
- int Indent)
- {
- int i, IsRational, NumCoords;
- char Str[LINE_LEN],
- *ErrStr = NULL;
- CagdRType *Coords;
- IPObjectStruct *PObjTmp;
- IPPolygonStruct *PPolygon;
- IPVertexStruct *PVertex;
- IPAttributeStruct
- *Attr = AttrTraceAttributes(PObj -> Attrs, PObj -> Attrs);
-
- if (Attr) {
- _IPFprintf(Handler, Indent, "[OBJECT\n");
-
- IritPrsrPutAttributes(Handler, Attr, Indent);
-
- _IPFprintf(Handler, Indent + 4,
- "%s\n", strlen(PObj -> Name) ? PObj -> Name : "NONE");
- }
- else {
- _IPFprintf(Handler, Indent, "[OBJECT %s\n",
- strlen(PObj -> Name) ? PObj -> Name : "NONE");
- }
- Indent += 4;
-
- switch (PObj -> ObjType) {
- case IP_OBJ_POLY:
- for (PPolygon = PObj -> U.Pl;
- PPolygon != NULL;
- PPolygon = PPolygon -> Pnext) {
- if (PPolygon -> PVertex == NULL)
- continue;
-
- if (IP_IS_POLYLINE_OBJ(PObj))
- _IPFprintf(Handler, Indent, "[POLYLINE ");
- else if (IP_IS_POINTLIST_OBJ(PObj))
- _IPFprintf(Handler, Indent, "[POINTLIST ");
- else
- _IPFprintf(Handler,
- Indent, "[POLYGON [PLANE %s %s %s %s] ",
- _IPReal2Str(PPolygon -> Plane[0]),
- _IPReal2Str(PPolygon -> Plane[1]),
- _IPReal2Str(PPolygon -> Plane[2]),
- _IPReal2Str(PPolygon -> Plane[3]));
-
- IritPrsrPutAttributes(Handler, PPolygon -> Attrs, Indent);
-
- for (PVertex = PPolygon -> PVertex -> Pnext, i = 1;
- PVertex != PPolygon -> PVertex && PVertex != NULL;
- PVertex = PVertex -> Pnext, i++);
- _IPFprintf(Handler, Indent + 4, "%d\n", i);
-
- PVertex = PPolygon -> PVertex;
- do { /* Assume at least one edge in polygon! */
- _IPFprintf(Handler, Indent + 4, "[");
-
- IritPrsrPutAttributes(Handler, PVertex -> Attrs, Indent);
-
- if (IP_IS_POLYLINE_OBJ(PObj) ||
- (IP_IS_POLYGON_OBJ(PObj) &&
- PT_APX_EQ(PPolygon -> Plane, PVertex -> Normal)))
- _IPFprintf(Handler, 0, "%s%s %s %s]\n",
- IP_IS_INTERNAL_VRTX(PVertex) ? "[INTERNAL] " : "",
- _IPReal2Str(PVertex -> Coord[0]),
- _IPReal2Str(PVertex -> Coord[1]),
- _IPReal2Str(PVertex -> Coord[2]));
- else if (IP_IS_POINTLIST_OBJ(PObj))
- _IPFprintf(Handler, 0, "%s %s %s]\n",
- _IPReal2Str(PVertex -> Coord[0]),
- _IPReal2Str(PVertex -> Coord[1]),
- _IPReal2Str(PVertex -> Coord[2]));
- else
- _IPFprintf(Handler, 0,
- "%s[NORMAL %s %s %s] %s %s %s]\n",
- IP_IS_INTERNAL_VRTX(PVertex) ? "[INTERNAL] " : "",
- _IPReal2Str(PVertex -> Normal[0]),
- _IPReal2Str(PVertex -> Normal[1]),
- _IPReal2Str(PVertex -> Normal[2]),
- _IPReal2Str(PVertex -> Coord[0]),
- _IPReal2Str(PVertex -> Coord[1]),
- _IPReal2Str(PVertex -> Coord[2]));
-
- PVertex = PVertex -> Pnext;
- }
- while (PVertex != PPolygon -> PVertex && PVertex != NULL);
- _IPFprintf(Handler, Indent, "]\n"); /* Close the polygon. */
- }
- break;
- case IP_OBJ_NUMERIC:
- _IPFprintf(Handler, Indent, "[NUMBER %s]\n",
- _IPReal2Str(PObj -> U.R));
- break;
- case IP_OBJ_POINT:
- _IPFprintf(Handler, Indent, "[POINT %s %s %s]\n",
- _IPReal2Str(PObj -> U.Pt[0]),
- _IPReal2Str(PObj -> U.Pt[1]),
- _IPReal2Str(PObj -> U.Pt[2]));
- break;
- case IP_OBJ_VECTOR:
- _IPFprintf(Handler, Indent, "[VECTOR %s %s %s]\n",
- _IPReal2Str(PObj -> U.Vec[0]),
- _IPReal2Str(PObj -> U.Vec[1]),
- _IPReal2Str(PObj -> U.Vec[2]));
- break;
- case IP_OBJ_PLANE:
- _IPFprintf(Handler, Indent, "[PLANE %s %s %s %s]\n",
- _IPReal2Str(PObj -> U.Plane[0]),
- _IPReal2Str(PObj -> U.Plane[1]),
- _IPReal2Str(PObj -> U.Plane[2]),
- _IPReal2Str(PObj -> U.Plane[3]));
- break;
- case IP_OBJ_CTLPT:
- Coords = PObj -> U.CtlPt.Coords;
- IsRational = CAGD_IS_RATIONAL_PT(PObj -> U.CtlPt.PtType);
- NumCoords = CAGD_NUM_OF_PT_COORD(PObj -> U.CtlPt.PtType);
-
- sprintf(Str, "[CTLPT %c%d %s", IsRational ? 'P' : 'E', NumCoords,
- IsRational ? _IPReal2Str(Coords[0]) : "");
-
- for (i = 1; i <= NumCoords; i++) {
- strcat(Str, " ");
- strcat(Str, _IPReal2Str(Coords[i]));
- }
- strcat(Str,"]\n");
- _IPFprintf(Handler, Indent, Str);
- break;
- case IP_OBJ_MATRIX:
- _IPFprintf(Handler, Indent, "[MATRIX\n");
- for (i = 0; i < 4; i++)
- _IPFprintf(Handler, Indent + 8, "%s %s %s %s%s\n",
- _IPReal2Str((*PObj -> U.Mat)[i][0]),
- _IPReal2Str((*PObj -> U.Mat)[i][1]),
- _IPReal2Str((*PObj -> U.Mat)[i][2]),
- _IPReal2Str((*PObj -> U.Mat)[i][3]),
- i == 3 ? "]" : "");
- break;
- case IP_OBJ_STRING:
- _IPFprintf(Handler, Indent, "[STRING \"%s\"]\n", PObj -> U.Str);
- break;
- case IP_OBJ_LIST_OBJ:
- for (i = 0; (PObjTmp = ListObjectGet(PObj, i)) != NULL; i++)
- IritPrsrPutAllObjects(PObjTmp, Handler, Indent);
- break;
- case IP_OBJ_CURVE:
- CagdCrvWriteToFile2(PObj -> U.Crvs, Handler,
- Indent, NULL, &ErrStr);
- if (ErrStr != NULL)
- _IPParserAbort(IP_ERR_CAGD_LIB_ERR, ErrStr);
- break;
- case IP_OBJ_SURFACE:
- CagdSrfWriteToFile2(PObj -> U.Srfs, Handler,
- Indent, NULL, &ErrStr);
- if (ErrStr != NULL)
- _IPParserAbort(IP_ERR_CAGD_LIB_ERR, ErrStr);
- break;
- case IP_OBJ_TRIMSRF:
- TrimWriteTrimmedSrfToFile2(PObj -> U.TrimSrfs, Handler,
- Indent, NULL, &ErrStr);
- if (ErrStr != NULL)
- _IPParserAbort(IP_ERR_TRIM_LIB_ERR, ErrStr);
- break;
- case IP_OBJ_TRIVAR:
- TrivTVWriteToFile2(PObj -> U.Trivars, Handler,
- Indent, NULL, &ErrStr);
- if (ErrStr != NULL)
- _IPParserAbort(IP_ERR_TRIV_LIB_ERR, ErrStr);
- break;
- default:
- IritPrsrFatalError("Attemp to print undefine object type.");
- break;
- }
-
- Indent -= 4;
- _IPFprintf(Handler, Indent, "]\n"); /* Close the object. */
- }
-
- /*****************************************************************************
- * DESCRIPTION: *
- * Same as fprintf but with indentation. *
- * See function IritPrsrSetPrintFunc, IritPrsrSetFloatFormat *
- * *
- * PARAMETERS: *
- * Handler: A handler to the open stream. *
- * Indent: All printing will start at this column. *
- * va_alist: Do "man stdarg" *
- * *
- * RETURN VALUE: *
- * void *
- *****************************************************************************/
- #ifdef USE_VARARGS
- void _IPFprintf(int Handler, int Indent, char *va_alist, ...)
- {
- char *Format, Line[LINE_LEN_LONG];
- int i;
- va_list ArgPtr;
-
- va_start(ArgPtr);
- Format = va_arg(ArgPtr, char *);
- #else
- void _IPFprintf(int Handler, int Indent, char *Format, ...)
- {
- char Line[LINE_LEN_LONG];
- int i;
- va_list ArgPtr;
-
- va_start(ArgPtr, Format);
- #endif /* USE_VARARGS */
-
- if (IritPrsrPrintFunc != NULL || _IPStream[Handler].f != NULL) {
- for (i = 0; Indent >= 8; i++, Indent -= 8)
- Line[i] = '\t';
- while (Indent--)
- Line[i++] = ' ';
- vsprintf(&Line[i], Format, ArgPtr);
-
- if (_IPStream[Handler].f != NULL)
- fprintf(_IPStream[Handler].f, Line);
- else
- IritPrsrPrintFunc(Line);
- }
- else { /* _IPStream[Handler].f == NULL and it is a socket connction. */
- /* No need for indentation if writing to a socket. */
- vsprintf(Line, Format, ArgPtr);
- SocWriteLine(Handler, Line, strlen(Line));
- }
-
- va_end(ArgPtr);
- }
-
- /*****************************************************************************
- * DESCRIPTION: *
- * Routine to print the attributes of given attribute list. *
- * *
- * PARAMETERS: *
- * Handler: A handler to the open stream. *
- * Attr: Attributes to put out. *
- * Indent: Indentation to put attributes at. *
- * *
- * RETURN VALUE: *
- * void *
- *****************************************************************************/
- static void IritPrsrPutAttributes(int Handler,
- IPAttributeStruct *Attr,
- int Indent)
- {
- Attr = AttrTraceAttributes(Attr, Attr);
-
- while (Attr) {
- if (Attr -> Type == IP_ATTR_OBJ) {
- _IPFprintf(Handler, Indent + 4, "[%s\n", Attr -> Name);
- IritPrsrPutAllObjects(Attr -> U.PObj, Handler, Indent + 8);
- _IPFprintf(Handler, Indent + 4, "]\n");
- }
- else
- _IPFprintf(Handler, Indent + 4, "%s\n", Attr2String(Attr));
-
- Attr = AttrTraceAttributes(Attr, NULL);
- }
- }
-
- /*****************************************************************************
- * DESCRIPTION: *
- * Convert a real number into a string. *
- * The routine maintains six different buffers simultanuously so up to six *
- * consecutive calls can be issued from same printf and stiil have valid *
- * strings. *
- * *
- * PARAMETERS: *
- * R: A real number to convert to a string. *
- * *
- * RETURN VALUE: *
- * char *: A string representing R. *
- *****************************************************************************/
- char *_IPReal2Str(RealType R)
- {
- static int j, k,
- i = 0;
- static char Buffer[6][LINE_LEN_SHORT], Line[LINE_LEN];
-
- if (ABS(R) < ZERO_NUM_EPSILON)
- R = 0.0; /* Round off very small numbers. */
-
- sprintf(Buffer[i], _IPGlblFloatFormat, R);
-
- for (k = 0; !isdigit(Buffer[i][k]) && k < LINE_LEN; k++);
- if (k >= LINE_LEN) {
- sprintf(Line, "Conversion of real number (%f) failed.", R);
- IritPrsrFatalError(Line);
- }
-
- for (j = strlen(Buffer[i]) - 1; Buffer[i][j] == ' ' && j > k; j--);
- if (strchr(Buffer[i], '.') != NULL &&
- strchr(Buffer[i], 'e') == NULL &&
- strchr(Buffer[i], 'E') == NULL)
- for (; Buffer[i][j] == '0' && j > k; j--);
- Buffer[i][j + 1] = 0;
-
- j = i;
- i = (i + 1) % 6;
- return Buffer[j];
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Returns a pointer to last vertex of a list. M
- * *
- * PARAMETERS: M
- * VList: A list of vertices M
- * *
- * RETURN VALUE: M
- * IPVertexStruct *: Last vertex in VList. M
- * *
- * KEYWORDS: M
- * IritPrsrGetLastVrtx, linked lists, last element M
- *****************************************************************************/
- IPVertexStruct *IritPrsrGetLastVrtx(IPVertexStruct *VList)
- {
- return IritPrsrGetPrevVrtx(VList, NULL);
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Returns a pointer to previous vertex in VList to V. M
- * *
- * PARAMETERS: M
- * VList: A list of vertices. M
- * V: For which the previous vertex in VList is pursuit. M
- * *
- * RETURN VALUE: M
- * IPVertexStruct *: Previous vertex to V in VList if found, NULL M
- * otherwise. M
- * *
- * KEYWORDS: M
- * IritPrsrGetPrevVrtx, previous element, linked lists M
- *****************************************************************************/
- IPVertexStruct *IritPrsrGetPrevVrtx(IPVertexStruct *VList, IPVertexStruct *V)
- {
- IPVertexStruct
- *VHead = VList;
-
- if (VList == NULL || VList == V)
- return NULL;
-
- for ( ;
- VList != NULL && VList -> Pnext != V && VList -> Pnext != VHead;
- VList = VList -> Pnext);
-
- return VList;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Appends two vertex lists together. M
- * *
- * PARAMETERS: M
- * VList1, VList2: Two lists to append. M
- * *
- * RETURN VALUE: M
- * IPVertexStruct *: Appended list. M
- * *
- * KEYWORDS: M
- * IritPrsrAppendVrtxLists, linked lists M
- *****************************************************************************/
- IPVertexStruct *IritPrsrAppendVrtxLists(IPVertexStruct *VList1,
- IPVertexStruct *VList2)
- {
- if (VList1 == NULL)
- return VList2;
- else if (VList2 == NULL)
- return VList1;
- else {
- IPVertexStruct
- *VLast = IritPrsrGetLastVrtx(VList1);
-
- VLast -> Pnext = VList2;
-
- return VList1;
- }
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Returns a pointer to last polygon/line of a list. M
- * *
- * PARAMETERS: M
- * PList: A list of polygons. M
- * *
- * RETURN VALUE: M
- * IPPolygonStruct *: Last polygon in list PList. M
- * *
- * KEYWORDS: M
- * IritPrsrGetLastPoly, linked lists, last element M
- *****************************************************************************/
- IPPolygonStruct *IritPrsrGetLastPoly(IPPolygonStruct *PList)
- {
- return IritPrsrGetPrevPoly(PList, NULL);
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Returns a pointer to previous polygon in PList to P. M
- * *
- * PARAMETERS: M
- * PList: A list of polygons. M
- * P: For which the previous polygon in PList is pursuit. M
- * *
- * RETURN VALUE: M
- * IPVertexStruct *: Previous polygon to P in PList if found, NULL M
- * otherwise. M
- * *
- * KEYWORDS: M
- * IritPrsrGetPrevPoly, previous element, linked lists M
- *****************************************************************************/
- IPPolygonStruct *IritPrsrGetPrevPoly(IPPolygonStruct *PList,
- IPPolygonStruct *P)
- {
- if (PList == NULL || PList == P)
- return NULL;
-
- for ( ; PList != NULL && PList -> Pnext != P; PList = PList -> Pnext);
-
- return PList;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Appends two poly lists together. M
- * *
- * PARAMETERS: M
- * PList1, PList2: Two lists to append. M
- * *
- * RETURN VALUE: M
- * IPPolygonStruct *: Appended list. M
- * *
- * KEYWORDS: M
- * IritPrsrAppendPolyLists, linked lists M
- *****************************************************************************/
- IPPolygonStruct *IritPrsrAppendPolyLists(IPPolygonStruct *PList1,
- IPPolygonStruct *PList2)
- {
- if (PList1 == NULL)
- return PList2;
- else if (PList2 == NULL)
- return PList1;
- else {
- IPPolygonStruct
- *PLast = IritPrsrGetLastPoly(PList1);
-
- PLast -> Pnext = PList2;
-
- return PList1;
- }
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Returns a pointer to last object of a list. M
- * *
- * PARAMETERS: M
- * OList: A list of objects. M
- * *
- * RETURN VALUE: M
- * IPPolygonStruct *: Last object in list OList. M
- * *
- * KEYWORDS: M
- * IritPrsrGetLastObj, linked lists, last element M
- *****************************************************************************/
- IPObjectStruct *IritPrsrGetLastObj(IPObjectStruct *OList)
- {
- return IritPrsrGetPrevObj(OList, NULL);
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Returns a pointer to previous object in OList to O. M
- * *
- * PARAMETERS: M
- * OList: A list of objects. M
- * O: For which the previous object in OList is pursuit. M
- * *
- * RETURN VALUE: M
- * IPVertexStruct *: Previous object to O in OList if found, NULL M
- * otherwise. M
- * *
- * KEYWORDS: M
- * IritPrsrGetPrevObj, previous element, linked lists M
- *****************************************************************************/
- IPObjectStruct *IritPrsrGetPrevObj(IPObjectStruct *OList, IPObjectStruct *O)
- {
- if (OList == NULL || OList == O)
- return NULL;
-
- for ( ; OList != NULL && OList -> Pnext != O; OList = OList -> Pnext);
- if (OList == NULL)
- return NULL;
-
- return OList;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Appends two object lists together. M
- * *
- * PARAMETERS: M
- * OList1, OList2: Two lists to append. M
- * *
- * RETURN VALUE: M
- * IPPolygonStruct *: Appended list. M
- * *
- * KEYWORDS: M
- * IritPrsrAppendObjLists, linked lists M
- *****************************************************************************/
- IPObjectStruct *IritPrsrAppendObjLists(IPObjectStruct *OList1,
- IPObjectStruct *OList2)
- {
- if (OList1 == NULL)
- return OList2;
- else if (OList2 == NULL)
- return OList1;
- else {
- IPObjectStruct
- *OLast = IritPrsrGetLastObj(OList1);
-
- OLast -> Pnext = OList2;
-
- return OList1;
- }
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Returns the length of a list of vertices. M
- * *
- * PARAMETERS: M
- * V: Vertex list to compute its length. M
- * *
- * RETURN VALUE: M
- * int: Number of elements in V list. M
- * *
- * KEYWORDS: M
- * IritPrsrVrtxListLen, length, linked lists M
- *****************************************************************************/
- int IritPrsrVrtxListLen(IPVertexStruct *V)
- {
- int i;
-
- for (i = 0; V != NULL; i++, V = V -> Pnext);
-
- return i;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Returns the length of a list of polygons. M
- * *
- * PARAMETERS: M
- * P: Polygon list to compute its length. M
- * *
- * RETURN VALUE: M
- * int: Number of elements in P list. M
- * *
- * KEYWORDS: M
- * IritPrsrPolyListLen, length, linked lists M
- *****************************************************************************/
- int IritPrsrPolyListLen(IPPolygonStruct *P)
- {
- int i;
-
- for (i = 0; P != NULL; i++, P = P -> Pnext);
-
- return i;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Returns the length of a list of objects. M
- * *
- * PARAMETERS: M
- * O: Object list to compute its length. M
- * *
- * RETURN VALUE: M
- * int: Number of elements in O list. M
- * *
- * KEYWORDS: M
- * IritPrsrObjListLen, length, linked lists M
- *****************************************************************************/
- int IritPrsrObjListLen(IPObjectStruct *O)
- {
- int i;
-
- for (i = 0; O != NULL; i++, O = O -> Pnext);
-
- return i;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Sets the printing function to call if needs to redirect printing. M
- * *
- * PARAMETERS: M
- * PrintFunc: A function that gets a single string it should print. M
- * *
- * RETURN VALUE: M
- * void M
- * *
- * KEYWORDS: M
- * IritPrsrSetPrintFunc, files M
- *****************************************************************************/
- void IritPrsrSetPrintFunc(IritPrsrPrintFuncType PrintFunc)
- {
- IritPrsrPrintFunc = PrintFunc;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Sets the floating point printing format. M
- * *
- * PARAMETERS: M
- * FloatFormat: A printf style floating point printing format string. M
- * *
- * RETURN VALUE: M
- * void M
- * *
- * KEYWORDS: M
- * IritPrsrSetFloatFormat, files M
- *****************************************************************************/
- void IritPrsrSetFloatFormat(char *FloatFormat)
- {
- char Str[LINE_LEN];
-
- /* Not a full-proof test but something. */
- if (strlen(FloatFormat) >= 2 &&
- strchr(FloatFormat, '%') != NULL &&
- (strchr(FloatFormat, 'e') != NULL ||
- strchr(FloatFormat, 'f') != NULL ||
- strchr(FloatFormat, 'g') != NULL ||
- strchr(FloatFormat, 'E') != NULL ||
- strchr(FloatFormat, 'F') != NULL ||
- strchr(FloatFormat, 'G') != NULL)) {
- _IPGlblFloatFormat = FloatFormat;
- }
- else {
- sprintf(Str, "Illegal floating point format \"%s\".", FloatFormat);
- IritPrsrFatalError(Str);
- }
- }
-